package com.cr.framework.web.service;

import com.cr.common.core.domain.entity.AppUser;
import com.cr.common.core.domain.model.AppLoginUser;
import com.cr.common.exception.ServiceException;
import com.cr.common.exception.user.UserPasswordNotMatchException;
import com.cr.framework.config.AppAuthenticationProvider;
import com.cr.framework.security.context.AuthenticationContextHolder;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录校验方法
 * 
 */
@Component
public class AppLoginService
{

    @Resource(name = "appAuthenticationProvider")
    private AppAuthenticationProvider appAuthenticationProvider;

    @Resource
    private AppTokenService appTokenService;

    /**
     * 登录验证
     * 
     * @param phone 用户名
     * @param password 密码
     */
    public Map<String, Object> appLogin(String phone, String password)
    {
        // 用户验证
        Authentication authentication;
        try {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = appAuthenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(phone, password));
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                throw new UserPasswordNotMatchException();
            } else {
                throw new ServiceException(e.getMessage());
            }
        } finally {
            AuthenticationContextHolder.clearContext();
        }
        AppLoginUser loginUser = (AppLoginUser) authentication.getPrincipal();
        // 生成token
        String token = appTokenService.createToken(loginUser);
        AppUser user = loginUser.getUser();

        Map<String, Object> data = new HashMap<>();
        data.put("token", token);
        data.put("phone", user.getPhone());
        data.put("nickName", user.getNickName());
        data.put("profile", user.getProfileUrl());
        data.put("authStatus", user.getAuthStatus());
        return data;
    }

}
